import numpy as np
from flask import Blueprint, render_template, jsonify, request
from flask_login import current_user
from sqlalchemy import func
from .tea_auth import teacher_login_required, add_registration
from .tea_utils import get_common_data
from ..models.models import Grade, db, Student, Class

# 创建蓝图
bp = Blueprint('tea_analysis', __name__)

"""
教师端成绩分析路由模块

提供教师进行成绩分析的功能，包括：
1. 页面路由：
   - /teacher/analysis: 统计分析主页面
   - /teacher/analysis/distribution: 成绩分布分析
   - /teacher/analysis/comparison: 班级对比分析
   - /teacher/analysis/trend: 成绩趋势分析
2. API路由：
   - GET /teacher/analysis/data: 获取各类分析数据
   - GET /teacher/analysis/progress/data: 获取成绩进步率分析数据
3. 分析函数：
   - get_grade_distribution: 计算成绩分布
   - get_class_comparison: 计算班级平均分对比
   - get_grade_trend: 计算成绩趋势

所有路由都需要教师登录权限，使用teacher_login_required装饰器进行保护。
部分路由使用add_registration装饰器自动添加注册信息。
"""

# ==================== 页面路由 ====================
@bp.route('/teacher/analysis/distribution')
@teacher_login_required
@add_registration
def distribution(registration):
    """
    成绩分布分析页面路由
    
    显示学生成绩的分布情况，包括：
    1. 各分数段人数统计
    2. 成绩分布图表
    3. 按学期筛选功能
    
    Args:
        registration: 教师注册信息，由add_registration装饰器提供
        
    Returns:
        str: 渲染后的成绩分布分析页面HTML
    """
    return render_template('teacher/analysis/distribution.html', 
                         registration=registration,
                         **get_common_data())

@bp.route('/teacher/analysis/comparison')
@teacher_login_required
@add_registration
def comparison(registration):
    """
    班级对比分析页面路由
    
    显示不同班级的成绩对比，包括：
    1. 各班级平均分对比
    2. 班级成绩分布对比
    3. 按学期筛选功能
    
    Args:
        registration: 教师注册信息，由add_registration装饰器提供
        
    Returns:
        str: 渲染后的班级对比分析页面HTML
    """
    return render_template('teacher/analysis/comparison.html', 
                         registration=registration,
                         **get_common_data())

@bp.route('/teacher/analysis/trend')
@teacher_login_required
@add_registration
def trend(registration):
    """
    成绩趋势分析页面路由
    
    显示学生成绩的变化趋势，包括：
    1. 各学期平均分趋势
    2. 成绩变化率分析
    3. 按课程筛选功能
    
    Args:
        registration: 教师注册信息，由add_registration装饰器提供
        
    Returns:
        str: 渲染后的成绩趋势分析页面HTML
    """
    return render_template('teacher/analysis/trend.html', 
                         registration=registration,
                         **get_common_data())

# ==================== API路由 ====================
@bp.route('/teacher/analysis/data')
@teacher_login_required
def get_analysis_data():
    """
    获取分析数据的API
    返回教师所需的所有分析数据，包括：
    1. 成绩分布数据
    2. 班级对比数据
    3. 成绩趋势数据
    4. 学期列表
    """
    try:
        # 获取筛选参数
        semester = request.args.get('semester', None)
        # 获取所有成绩数据
        grades_query = Grade.query
        if semester:
            grades_query = grades_query.filter_by(semester=semester)
        grades = grades_query.all()
        if not grades:
            return jsonify({
                'success': False,
                'message': '未找到成绩数据'
            })
        # 计算各种分析数据
        distribution = get_grade_distribution(grades)    # 成绩分布
        class_comparison = get_class_comparison(grades)  # 班级对比
        trend = get_grade_trend(grades)                  # 成绩趋势
        # 获取所有学期
        semesters = db.session.query(Grade.semester)\
            .distinct()\
            .order_by(Grade.semester)\
            .all()
        semester_list = [semester[0] for semester in semesters]
        return jsonify({
            'success': True,
            'data': {
                'distribution': distribution,
                'classComparison': class_comparison,
                'trend': trend,
                'semesters': semester_list
            }
        })
    except Exception as e:
        return jsonify({
            'success': False,
            'message': f'获取数据失败：{str(e)}'
        })

# ==================== 分析函数 ====================
def get_grade_distribution(grades):
    """
    计算成绩分布
    
    统计各分数段的学生人数，分数段划分：
    - 不及格：0-60分
    - 60-70分
    - 70-80分
    - 80-90分
    - 90-100分
    
    Args:
        grades (list): 成绩对象列表，每个对象应包含total_score属性
        
    Returns:
        dict: 包含以下键的字典：
            - labels: 分数段标签列表
            - values: 各分数段人数列表
    """
    # 定义分数段
    ranges = [(0, 60), (60, 70), (70, 80), (80, 90), (90, 101)]
    labels = ['不及格', '60-70分', '70-80分', '80-90分', '90-100分']
    values = [0] * len(ranges)
    
    # 统计各分数段人数
    for grade in grades:
        score = float(grade.total_score) if grade.total_score is not None else 0
        for i, (low, high) in enumerate(ranges):
            if low <= score < high:
                values[i] += 1
                break
    
    return {
        'labels': labels,
        'values': values
    }

def get_class_comparison(grades):
    """
    计算班级平均分对比
    
    计算每个班级的平均分，并按班级名称排序。
    对于没有成绩的班级，其平均分记为0。
    
    Args:
        grades (list): 成绩对象列表，每个对象应关联到Student和Class
        
    Returns:
        dict: 包含以下键的字典：
            - labels: 班级名称列表
            - values: 各班级平均分列表
    """
    # 按班级分组计算平均分
    class_avg = {}
    for grade in grades:
        if not grade.student:
            continue
        student_class = getattr(grade.student, 'class', None)
        if not student_class:
            continue
        class_name = student_class.class_name
        if class_name not in class_avg:
            class_avg[class_name] = []
        if grade.total_score is not None:
            class_avg[class_name].append(float(grade.total_score))
    
    # 计算每个班级的平均分
    labels = []
    values = []
    for class_name, scores in class_avg.items():
        if scores:  # 只显示有成绩数据的班级
            labels.append(class_name)
            values.append(round(sum(scores) / len(scores), 2))
    
    return {
        'labels': labels,
        'values': values
    }

def get_grade_trend(grades):
    """
    计算成绩趋势
    
    按学期统计平均分的变化趋势，包括：
    1. 各学期平均分
    2. 成绩变化率
    
    Args:
        grades (list): 成绩对象列表，每个对象应包含semester和total_score属性
        
    Returns:
        dict: 包含以下键的字典：
            - labels: 学期列表
            - values: 各学期平均分列表
            - changes: 各学期成绩变化率列表（第一个学期为0）
    """
    # 按学期排序
    sorted_grades = sorted(grades, key=lambda x: x.semester if x.semester else '')
    
    # 计算每个学期的平均分
    semesters = []
    avg_scores = []
    current_semester = None
    current_scores = []
    
    for grade in sorted_grades:
        if not grade.semester or grade.total_score is None:
            continue
            
        if grade.semester != current_semester:
            if current_semester is not None and current_scores:
                semesters.append(current_semester)
                avg_scores.append(round(sum(current_scores) / len(current_scores), 2))
            current_semester = grade.semester
            current_scores = [float(grade.total_score)]
        else:
            current_scores.append(float(grade.total_score))
    
    # 添加最后一个学期的数据
    if current_scores:
        semesters.append(current_semester)
        avg_scores.append(round(sum(current_scores) / len(current_scores), 2))
    
    # 计算成绩变化率
    changes = []
    for i in range(1, len(avg_scores)):
        change = ((avg_scores[i] - avg_scores[i-1]) / avg_scores[i-1]) * 100 if avg_scores[i-1] != 0 else 0
        changes.append(round(change, 2))
    
    return {
        'labels': semesters,
        'values': avg_scores,
        'changes': changes
    }
